
from Tkinter import *
import math
import ctypes

SET_SERVO = 1
KILL_CREEPA = 2
TOWERTIMEARRAY = 3
KILL_CREEPB = 4
GET_RA0 = 5
FIRING = 6
GET_TOWERTYPE = 7
GET_TOWERPOS = 8
GET_TICK = 9

#[(32, 16, math.pi/4),(29, 24, 13*math.pi/12),(29, 33, math.pi/24),(9, 34, 23*math.pi/24),(17, 21.5, 13*math.pi/12),(9, 12, -math.pi/4)]


usb = ctypes.cdll.LoadLibrary('usb.dll')
usb.initialize()

buffer = ctypes.c_buffer(8)

def rad_to_delay(angle): #0 - 2pi --> 45 - 135 = ~240deg
    angle = angle%(2*math.pi)
    if 0 < angle < math.pi/3:
        return 55*angle + 80
    if math.pi/3 < angle <= math.pi/2:
        return 135
    if math.pi/2 < angle < 2*math.pi/3:
        return 25
    if 2*math.pi/3 < angle < 2*math.pi:
        return 55*(angle-240) + 25



def set_servo_callback(value):
    usb.control_transfer(dev, 0x40, SET_SERVO, int(value), 0, 0, buffer)

def update_clock():
    usb.control_transfer(dev, 0xC0, GET_TICK, 0, 0, 1, buffer)
    tick = ord(buffer[0])
    print tick
    update_clock()
    root.after(50, update_status(tick))

def update_creep():
    usb.control_transfer(dev, 0xC0, GET_CREEP, 0, 0, 1, buffer)
    creep = ord(buffer[0])
    print tick
    root.after(50, update_status(tick))
    
def update_status(value):
    status.configure(text = 'RA0 is currently %d.' % value)
    root.after(50, update_status)
    
def update_towertype():
    usb.control_transfer(dev, 0xC0, GET_TOWERTYPE, 0, 0, 1, buffer)
    towertype = [0]
    for i in range(len(buffer)):
        towertype[i] = ord(buffer[i])
    print towertype
    root.after(50, update_status)

def get_towerpos():
    usb.control_transfer(dev, 0xC0, GET_TOWERPOS, 0, 0, 1, buffer)
    towerbyte = ord(buffer[0])
    print towerbyte
    active_tower = [0,0,0,0,0,0]  #1 = 128, 2 = 64, 3 = 32, 4 = 16, 5 = 8, 6 = 4
    for i in range(6):
        if towerbyte >= 2**(7-i):
            active_tower[i] = 1
            towerbyte -= 2**(7-i)
    print active_tower
        

def kill(value):
    print "kill_spot is %s" %value
    if value < 8:
        usb.control_transfer(dev, 0x40, KILL_CREEPA, int(value), 0, 0, buffer)
    else:
        usb.control_transfer(dev, 0x40, KILL_CREEPB, int(value-8), 0, 0, buffer)



tower_delays = ctypes.c_buffer(64)

global n
n = 45
def update_tower_time():
    global n
    n += 5
    firing_array = [0,0,0,1,0,1,0,0]
    time_list = []
    for i in range(8):
        time_list.append(n)
    update_towers(time_list, firing_array)


def update_towers(time_list, firing_array): 
    firing_byte = 0
    for j in range(len(firing_array)):
        firing_byte += (2**j)*firing_array[7-j]
    for i in range (8):
        val = int(70.*int(time_list[i])/256+45)
        print val
        tower_delays[i] = chr(val)
    usb.control_transfer(dev, 0x40, TOWERTIMEARRAY, 0, 0, len(tower_delays), tower_delays)
    usb.control_transfer(dev, 0xC0, FIRING, firing_byte, 0, 1, buffer)


root = Tk()
root.title('Lab 3 GUI')
fm = Frame(root)
#Button(fm, text = 'SET_RA1', command = set_ra1_callback).pack(side = LEFT)
#Button(fm, text = 'CLR_RA1', command = clr_ra1_callback).pack(side = LEFT)
# Button(fm, text = 'GET_RA2', command = get_ra2_callback).pack(side = LEFT)

Button(fm, text = 0, command = lambda : kill(0)).pack(side = LEFT)
Button(fm, text = 1, command = lambda : kill(1)).pack(side = LEFT)
Button(fm, text = 2, command = lambda : kill(2)).pack(side = LEFT)
Button(fm, text = 3, command = lambda : kill(3)).pack(side = LEFT)
Button(fm, text = 4, command = lambda : kill(4)).pack(side = LEFT)
Button(fm, text = 5, command = lambda : kill(5)).pack(side = LEFT)
Button(fm, text = 6, command = lambda : kill(6)).pack(side = LEFT)
Button(fm, text = 7, command = lambda : kill(7)).pack(side = LEFT)
Button(fm, text = 8, command = lambda : kill(8)).pack(side = LEFT)
Button(fm, text = 9, command = lambda : kill(9)).pack(side = LEFT)
Button(fm, text = 10, command = lambda : kill(10)).pack(side = LEFT)
Button(fm, text = 11, command = lambda : kill(11)).pack(side = LEFT)
Button(fm, text = 12, command = lambda : kill(12)).pack(side = LEFT)
Button(fm, text = 13, command = lambda : kill(13)).pack(side = LEFT)
Button(fm, text = 14, command = lambda : kill(14)).pack(side = LEFT)
Button(fm, text = 15, command = lambda : kill(15)).pack(side = LEFT)


fm.pack(side = TOP)
##servoslider = Scale(root, from_ = 0, to = 255, orient = HORIZONTAL, showvalue = FALSE, command = update_tower_time)
##servoslider.set(128)
##servoslider.pack(side = TOP)
fr=Frame(root)
Button(fr, text = 'update_clock', command = update_clock).pack(side = LEFT)
Button(fr, text = "update_towers", command = update_tower_time).pack(side = LEFT)
Button(fr, text = 'get_towerpos', command = get_towerpos).pack(side = LEFT)
fr.pack(side = TOP)
status = Label(root, text = 'creep_checkin is currently ?.')
status.pack(side = TOP)

dev = usb.open_device(0x6666, 0x0003, 0)
if dev<0:
    print "No matching device found...\n"
else:
    ret = usb.control_transfer(dev, 0x00, 0x09, 1, 0, 0, buffer)
    if ret<0:
        print "Unable to send SET_CONFIGURATION standard request.\n"
    #root.after(50, update_status)
    root.mainloop()
    usb.close_device(dev)

